package com.backend.demo.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;

public class CollectionUtils {

	public static boolean isEmpty(Collection<?> coll) {
		return coll == null || coll.isEmpty();
	}

	public static boolean isNotEmpty(Collection<?> coll) {
		return !isEmpty(coll);
	}

	/**
	 * 判断Collection是否不为空
	 * 
	 * @param collection
	 * @return
	 */
	static public boolean notEmpty(Collection<?> collection) {
		return !empty(collection);
	}

	/**
	 * 判断Map是否不为空
	 * 
	 * 
	 * @param map
	 * @return
	 */
	static public boolean notEmpty(Map<?,?> map) {
		return !empty(map);
	}

	/**
	 * 判断Object[]是否不为空
	 * 
	 * 
	 * @param os
	 * @return
	 */
	static public boolean notEmpty(Object[] os) {
		return !empty(os);
	}

	public static boolean empty(Collection<?> collection) {
		return collection == null || collection.isEmpty();
	}

	public static boolean empty(Map<?,?> map) {
		return map == null || map.isEmpty();
	}

	public static boolean empty(Object[] os) {
		return os == null || os.length == 0;
	}

	public static boolean empty(long[] os) {
		return os == null || os.length == 0;
	}

	/**
	 * 把Iterator转换为List
	 * 
	 * @param it
	 *            Iterator
	 * @return List
	 */
	public static List toList(Iterator it) {
		ArrayList<Object> r = new ArrayList<Object>();
		while (it.hasNext()) {
			r.add(it.next());
		}
		return r;
	}

	public static <V> List<V> toList(List lst, Caster<V> co) {
		return toList(lst.iterator(), co);
	}

	public static <V> List<V> toList(Iterator it, Caster<V> co) {
		List<V> r = new ArrayList<V>();
		while (it.hasNext()) {
			r.add(co.cast(it.next()));
		}
		return r;
	}

	public static <V> List<V> toList(Iterator it, Class<V> cls) {
		List<V> r = new ArrayList<V>();
		while (it.hasNext()) {
			r.add(cls.cast(it.next()));
		}
		return r;
	}

	@SuppressWarnings("unchecked")
	public static <V> List<V> toList(List it, Class<V> cls) {
		return (List<V>) it;
	}

	/**
	 * 合并两个List的数据,只保留相同的数据.就是两个集合的交集<br>
	 * <code>
	 * lst1 : [1,2,3] <br>
	 * lst2 : [2,3]<br>
	 * uninonList result is [2,3]</code>
	 * 
	 * @param <V>
	 * @param lst1
	 * @param lst2
	 * @return
	 */
	public static <V> List<V> unionList(List<V> lst1, List<V> lst2) {
		List<V> lst = new ArrayList<V>();

		if (lst1 == null && lst2 == null) {
			return lst;
		}
		if (lst1 == null) {
			return lst2;
		}
		if (lst2 == null) {
			return lst1;
		}

		for (V v : lst1) {
			if (lst2.contains(v)) {
				lst.add(v);
			}
		}
		return lst;
	}

	/**
	 * 交集两个List的数据,只保留相同的数据.就是两个集合的交集<br>
	 * <code>
	 * lst1 : [1,2,3] <br>
	 * lst2 : [2,3]<br>
	 * uninonList result is [2,3]</code>
	 * 
	 * @param <V>
	 * @param lst1
	 * @param lst2
	 * @return
	 */
	public static <V> List<V> intersectList(List<V> lst1, List<V> lst2) {
		List<V> lst = new ArrayList<V>();

		if (lst1 == null && lst2 == null) {
			return lst;
		}
		if (lst1 == null) {
			return lst2;
		}
		if (lst2 == null) {
			return lst1;
		}

		for (V v : lst1) {
			if (lst2.contains(v)) {
				lst.add(v);
			}
		}
		return lst;
	}
	/**
	 * (合集-交集)两个集合进行合集减去交集操作,返回集合a与集合b的不共同元素
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static Collection<?> disjunction(Collection<?> a, Collection<?> b) {
		return CollectionUtils.disjunction(a, b);
	}

	/**
	 * (减去)两个集合进行相减操作,用集合a的元素减去集合b.返回的集合不包含集合b中的元素
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static Collection<?> subtract(Collection<?> a, Collection<?> b) {
		return CollectionUtils.subtract(a, b);
	}

	/**
	 * (并集)两个集合进行并集操作,用集合a的元素加上集合b(不重复).
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static Collection<?> union(Collection<?> a, Collection<?> b) {
		return CollectionUtils.union(a, b);
	}

	/**
	 * (交集)两个集合进行交集操作,用集合a的元素加上集合b(不重复).
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static Collection<?> intersection(Collection<?> a, Collection<?> b) {
		return CollectionUtils
				.intersection(a, b);
	}

	/**
	 * 添加所有元素到Collection中
	 * 
	 * @param collection
	 * @param iterator
	 */
	public static void addAll(Collection<?> collection, Iterator<?> iterator) {
		CollectionUtils.addAll(collection,
				iterator);
	}

	/**
	 * 添加所有元素到Collection中
	 * 
	 * @param collection
	 * @param enumeration
	 */
	public static void addAll(Collection<?> collection, Enumeration<?> enumeration) {
		CollectionUtils.addAll(collection,
				enumeration);
	}

	/**
	 * 添加所有元素数组到Collection中
	 * 
	 * @param collection
	 * @param elements
	 */
	public static void addAll(Collection<?> collection, Object[] elements) {
		CollectionUtils.addAll(collection,
				elements);
	}

	/**
	 * 合并两个List的数据,只保留相同的数据.就是两个集合的交集<br>
	 * <code>
	 * lst1 : [1,2,3] <br>
	 * lst2 : [2,3]<br>
	 * uninonList result is [2,3]</code>
	 * 
	 * @param <V>
	 * @param lst1
	 * @param lst2
	 * @return
	 */
	public static <V> Collection<V> addCollection(Collection<V> lst1,
			Collection<V> lst2) {
		List<V> lst = new ArrayList<V>();

		if (lst1 == null && lst2 == null) {
			return lst;
		}
		if (lst1 == null) {
			return lst2;
		}
		if (lst2 == null) {
			return lst1;
		}

		lst.addAll(lst1);
		for (V v : lst2) {
			if (!lst1.contains(v)) {
				lst.add(v);
			}
		}
		return lst;
	}

	/**
	 * 移除lst2在lst1中的数据<br>
	 * 
	 * @param <V>
	 * @param lst1
	 * @param lst2
	 * @return
	 */
	public static <V> List<V> remove(List<V> lst1, List<V> lst2) {
		List<V> lst = new ArrayList<V>();

		if (isEmpty(lst1) && isEmpty(lst2)) {
			return lst;
		}

		if (isEmpty(lst1)) {
			return lst1;
		}

		if (isEmpty(lst2)) {
			return lst1;
		}

		for (V v : lst1) {
			if (!lst2.contains(v)) {
				lst.add(v);
			}
		}
		return lst;
	}

	public static <V> List<V> itToList(Iterator<V> it) {
		ArrayList<V> r = new ArrayList<V>();
		while (it.hasNext()) {
			r.add(it.next());
		}
		return r;

	}

	/**
	 * 清空Collection
	 * 
	 * @param tempList
	 */
	public static void clearCollection(Collection<?> tempList) {
		if (isEmpty(tempList))
			return;
		tempList.clear();
		tempList = null;
	}

	public static void clearNull(Collection<?> lst) {
		if (lst != null) {
			Iterator<?> it = lst.iterator();
			while (it.hasNext()) {
				if (it.next() == null) {
					it.remove();
				}
			}
		}
	}

	/**
	 * 根据size分成多个列表<BR>
	 * 如果一个list有4500条数据.调用splitBySize(lst,1000);按1000分的话.将得到5个列表,1-4个列表各1000记录,
	 * 第5个列表有500条件数据
	 * 
	 * @param <T>
	 * @param lst
	 * @param size
	 * @return
	 */
	public static <T> List<List<T>> splitBySize(List<T> lst, int size) {
		if (isEmpty(lst) || size <= 0) {
			return null;
		}
		int count = 0;
		List<T> tmp = null;
		List<List<T>> result = new ArrayList<List<T>>();
		Iterator<T> it = lst.iterator();

		while (it.hasNext()) {
			if (count == 0 || count % size == 0) {
				tmp = new ArrayList<T>();
				result.add(tmp);
			}
			tmp.add(it.next());
			count++;
		}
		return result;
	}

	public static boolean isCollection(Object value) {
		Assert.notNull(value);
		if (value instanceof Collection || value.getClass().isArray()
				|| value instanceof Map) {
			return true;
		}
		return false;
	}

	public static boolean isNotCollection(Object value) {
		return !isCollection(value);
	}

	/**
	 * 将一个对象转换成 集合，如果该 对象不是集合、数组时返回null
	 * 
	 * @param value
	 * @return
	 */
	public static Collection<?> toCollection(Object value) {
		if (value == null) {
			return null;
		}
		if (value instanceof Collection<?>) {
			return (Collection<?>) value;
		}
		if (value instanceof Object[]) {
			Object[] v = (Object[]) value;
			return Arrays.asList(v);
		}
		if (ClassUtils.isPrimitiveArray(value.getClass())) {
			// 基本类型数组转换成对象数组
			Object[] v = ObjectUtils.toObjectArray(value);
			return Arrays.asList(v);
		}
		return null;
	}
	
	public static void main(String[] args) {
		System.out.println(toCollection(new Number[]{1L,1D}));
	}

	/**
	 * 根据list中的属性进行汇总(sum),要进行汇总的属性的类型必须为Number类型的子类
	 * 
	 * @param list
	 * @param propertyName
	 * @return
	 */
	public static Double sumByProperty(Collection<?> list, String propertyName) {
		if (empty(list) || propertyName == null) {
			return 0.0;
		}

		Double ret = 0.0;
		for (Object o : list) {
			Object fieldValue = ClassUtil.getFieldValue(o, propertyName);
			if (fieldValue == null || !(fieldValue instanceof Number)) {
				continue;
			}
			ret = MathUtil.add(ret, ((Number) fieldValue).doubleValue());
		}

		return ret;
	}
}
